/******************************************************************************
 * * desktop_menu.c - implementation of menu functions
 *
 * *(C) Copyright 2019 Asr International Ltd.
 * * All Rights Reserved
 * ******************************************************************************/
#include "desktop_global.h"


/**
 * Callback function for handling key pressed on Menu interface
 * param (in) Obj: lv_obj_t *
 * param (in) Key_Sta: UI_KEY_STATUS
 * param (in) Key_Val: UI_KEY_VALUE
 * return  UINT8
 */
UINT8 Framework_Menu_Key_Cb(lv_obj_t *Obj, UI_KEY_STATUS Key_Sta, UI_KEY_VALUE Key_Val)
{
    UI_Page_Multi_Button_Desc_t *PageMultiButton;
    UINT8                       RowNum;
    UINT8                       LastBtnIndex;
    lv_obj_t                    *TitleLabel;
    lv_obj_t                    *FocusBtn;
    Framework_App_t             *App;
    VOID                        *Param;

    if (KEY_RELEASED == Key_Sta)
    {
        Param           = Nav_Get_Param(ACT_ID_MENU);
        PageMultiButton = &(((UI_Normal_Menu_Desc_t *)Param)->PageMultiButton);
        FocusBtn        = PageMultiButton->ButtonList[PageMultiButton->FocusOnBtn].Button;
        TitleLabel      = ((UI_Normal_Menu_Desc_t *)Param)->TitleBar.Label;

        switch (Key_Val)
        {
        case KEY_SOFTRIGHT:
            Nav_Back(ACT_ID_ANY);
            break;

        case KEY_END:
            if (TRUE == g_FrameworkMng.CallingFlg)
            {
                Call_Framework_Disconnect_Req();
            }
            else
            {
                Nav_Home(ACT_ID_ANY);
            }
            break;

        case KEY_UP:
        case KEY_DOWN:
        case KEY_LEFT:
        case KEY_RIGHT:
            lv_btn_set_state(FocusBtn, LV_BTN_STATE_RELEASED);

            LastBtnIndex = PageMultiButton->ListButtonCnt - 1;
            switch (Key_Val)
            {
            case KEY_UP:
                if (2 < PageMultiButton->FocusOnBtn)
                {
                    PageMultiButton->FocusOnBtn -= 3;
                }
                else
                {   /* The current button is on the first row */
                    RowNum = PageMultiButton->ListButtonCnt / 3;
                    if (LastBtnIndex < (PageMultiButton->FocusOnBtn + RowNum * 3))
                    {
                        PageMultiButton->FocusOnBtn += (RowNum - 1) * 3;
                    }
                    else
                    {
                        PageMultiButton->FocusOnBtn += RowNum * 3;
                    }
                }
                break;

            case KEY_DOWN:
                if (LastBtnIndex < (PageMultiButton->FocusOnBtn + 3))
                {
                    PageMultiButton->FocusOnBtn = PageMultiButton->FocusOnBtn % 3;
                }
                else
                {
                    PageMultiButton->FocusOnBtn += 3;
                }
                break;

            case KEY_LEFT:
                if (0 == PageMultiButton->FocusOnBtn)
                {
                    PageMultiButton->FocusOnBtn = LastBtnIndex;
                }
                else
                {
                    PageMultiButton->FocusOnBtn--;
                }
                break;

            case KEY_RIGHT:
                if (LastBtnIndex == PageMultiButton->FocusOnBtn)
                {
                    PageMultiButton->FocusOnBtn = 0;
                }
                else
                {
                    PageMultiButton->FocusOnBtn++;
                }
                break;

            default:
                break;
            } /* switch */

            FocusBtn = PageMultiButton->ButtonList[PageMultiButton->FocusOnBtn].Button;
            App      = (Framework_App_t *)FocusBtn->user_data.user_data;
            lv_label_set_text(TitleLabel, lv_lang_get_text(App->NameTextId));
            lv_btn_set_state(FocusBtn, LV_BTN_STATE_PRESSED);
            lv_page_focus(PageMultiButton->Page, FocusBtn, 0);
            break;

        case KEY_OK:
            App = (Framework_App_t *)FocusBtn->user_data.user_data;
            App->AppFunc();
            break;

        default:
            break;
        } /* switch */
    }

    return(1);
} /* Framework_Menu_Key_Cb */


/**
 * Callback function for additional actions after Creating Menu interface
 * param (in) Ctrl: VOID *
 * return  VOID
 */
VOID Framework_Menu_OnCreate(VOID *Ctrl)
{
    UI_Page_Multi_Button_Desc_t *PageMultiButton = &(((UI_Normal_Menu_Desc_t *)Ctrl)->PageMultiButton);
    lv_obj_t                    *TitleLabel      = ((UI_Normal_Menu_Desc_t *)Ctrl)->TitleBar.Label;
    Framework_App_t             *App;
    UINT8                       i = 0;
    lv_obj_t                    *FocusBtn;
    
    App = g_FrameworkMng.AppList;
    while (NULL != App)
    {
        PageMultiButton->ButtonList[i].Button->user_data.user_data = (VOID *)App;
        i++;

        App = App->Next;
    }

    FocusBtn = PageMultiButton->ButtonList[PageMultiButton->FocusOnBtn].Button;
    App      = (Framework_App_t *)FocusBtn->user_data.user_data;
    lv_label_set_text(TitleLabel, lv_lang_get_text(App->NameTextId));
}


/**
 * Callback function for restoring state on Menu interface after backward from another activity
 * param (in) Ctrl: VOID *
 * return  VOID
 */
VOID Framework_Menu_OnRestoreState(VOID *Ctrl)
{
    UI_Page_Multi_Button_Desc_t *PageMultiButton = &(((UI_Normal_Menu_Desc_t *)Ctrl)->PageMultiButton);
    lv_obj_t                    *TitleLabel      = ((UI_Normal_Menu_Desc_t *)Ctrl)->TitleBar.Label;
    Framework_App_t             *App;
    UINT8                       i = 0;
    lv_obj_t                    *FocusBtn;

    App = g_FrameworkMng.AppList;
    while (NULL != App)
    {
        PageMultiButton->ButtonList[i].Button->user_data.user_data = (VOID *)App;
        i++;

        App = App->Next;
    }

    FocusBtn = PageMultiButton->ButtonList[PageMultiButton->FocusOnBtn].Button;
    App      = (Framework_App_t *)FocusBtn->user_data.user_data;
    lv_label_set_text(TitleLabel, lv_lang_get_text(App->NameTextId));
}


/**
 * Public callback function for destroying Menu interface which will be popped from stack
 * param (in) Ctrl: VOID *
 * return  VOID
 */
VOID Framework_Menu_OnDestroy(VOID *Ctrl)
{
    Hal_Mem_Free(((UI_Normal_Menu_Desc_t *)Ctrl)->PageMultiButton.ButtonList);
    Hal_Mem_Free(Ctrl);
}


/**
 * Create Menu for Call APP
 * param (in) VOID
 * return  VOID
 */
VOID Framework_Call_Menu_Main(VOID)
{
    Nav_Func_List_t       FuncList;
    UI_Normal_Menu_Desc_t *NormalMenuDesc;
    Framework_App_t       *App = g_FrameworkMng.AppList;
    UINT8                 i    = 0;
    UINT32                Len;

    NormalMenuDesc = (UI_Normal_Menu_Desc_t *)Hal_Mem_Alloc(sizeof(UI_Normal_Menu_Desc_t));
    Hal_Mem_Set(NormalMenuDesc, 0, sizeof(UI_Normal_Menu_Desc_t));

    NormalMenuDesc->TitleBar.TxtId      = LV_LANG_TXT_ID_NONE;
    NormalMenuDesc->TitleBar.TxtAlign   = LV_LABEL_ALIGN_CENTER;
    NormalMenuDesc->TitleBar.LabelAlign = LV_ALIGN_IN_TOP_LEFT;

    while (NULL != App)
    {
        NormalMenuDesc->PageMultiButton.ListButtonCnt++;

        App = App->Next;
    }

    Len                                        = sizeof(UI_Menu_Button_Desc_t) * NormalMenuDesc->PageMultiButton.ListButtonCnt;
    NormalMenuDesc->PageMultiButton.ButtonList = (UI_Menu_Button_Desc_t *)Hal_Mem_Alloc(Len);
    Hal_Mem_Set(NormalMenuDesc->PageMultiButton.ButtonList, 0, Len);

    App = g_FrameworkMng.AppList;
    while (NULL != App)
    {
        NormalMenuDesc->PageMultiButton.ButtonList[i].Icon = App->AppImage;
        i++;

        App = App->Next;
    }

    if (5 <= NormalMenuDesc->PageMultiButton.ListButtonCnt)
    {
        NormalMenuDesc->PageMultiButton.FocusOnBtn = 4;
    }
    else
    {
        NormalMenuDesc->PageMultiButton.FocusOnBtn = NormalMenuDesc->PageMultiButton.ListButtonCnt - 1;
    }

    NormalMenuDesc->KeyFunc = Framework_Menu_Key_Cb;

    NormalMenuDesc->ButtonBar.ButtonL.Valid = FALSE;
    NormalMenuDesc->ButtonBar.ButtonM.Valid = TRUE;
    NormalMenuDesc->ButtonBar.ButtonM.TxtId = PHONE_TEXT_ID_SELECT;

    NormalMenuDesc->ButtonBar.ButtonR.Valid = TRUE;
    NormalMenuDesc->ButtonBar.ButtonR.TxtId = PHONE_TEXT_ID_EXIT;

    Hal_Mem_Set(&FuncList, 0, sizeof(Nav_Func_List_t));
    FuncList.OnShow         = UI_Normal_Menu_Create;
    FuncList.OnCreate       = Framework_Menu_OnCreate;
    FuncList.OnRestoreState = Framework_Menu_OnRestoreState;
    FuncList.OnSaveState    = Framework_Interface_OnSaveState;
    FuncList.OnDestroy      = Framework_Menu_OnDestroy;

    Nav_Forward(ACT_ID_ANY, ACT_ID_MENU, &FuncList, NormalMenuDesc);
} /* Framework_Call_Menu_Main */
